/**
 * 生成模拟表数据脚本 (ESM版本)
 * 用于离线开发和测试文档生成
 */

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// 获取当前文件目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 配置
const OUTPUT_DIR = path.resolve(__dirname, '../tables');
const TYPES_DIR = path.resolve(__dirname, '../types');
const RAW_DATA_DIR = path.resolve(__dirname, '../raw-data');

// 确保目录存在
[OUTPUT_DIR, TYPES_DIR, RAW_DATA_DIR].forEach(dir => {
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
        console.log(`创建目录: ${dir}`);
    }
});

// 模拟表模板
const MOCK_TABLES = [
    {
        name: 'user',
        comment: '用户表',
        columns: [
            { name: 'id', type: 'int', nullable: false, isPrimary: true, comment: '用户ID' },
            { name: 'username', type: 'varchar', nullable: false, comment: '用户名' },
            { name: 'password', type: 'varchar', nullable: false, comment: '密码（哈希值）' },
            { name: 'email', type: 'varchar', nullable: true, comment: '邮箱' },
            { name: 'phone', type: 'varchar', nullable: true, comment: '手机号' },
            { name: 'created_at', type: 'timestamp', nullable: false, comment: '创建时间' },
            { name: 'updated_at', type: 'timestamp', nullable: false, comment: '更新时间' }
        ]
    },
    {
        name: 'product',
        comment: '产品表',
        columns: [
            { name: 'id', type: 'int', nullable: false, isPrimary: true, comment: '产品ID' },
            { name: 'name', type: 'varchar', nullable: false, comment: '产品名称' },
            { name: 'description', type: 'text', nullable: true, comment: '产品描述' },
            { name: 'price', type: 'decimal', nullable: false, comment: '价格' },
            { name: 'stock', type: 'int', nullable: false, comment: '库存数量' },
            { name: 'category_id', type: 'int', nullable: true, comment: '分类ID' },
            { name: 'created_at', type: 'timestamp', nullable: false, comment: '创建时间' },
            { name: 'updated_at', type: 'timestamp', nullable: false, comment: '更新时间' }
        ]
    },
    {
        name: 'order',
        comment: '订单表',
        columns: [
            { name: 'id', type: 'int', nullable: false, isPrimary: true, comment: '订单ID' },
            { name: 'user_id', type: 'int', nullable: false, comment: '用户ID' },
            { name: 'status', type: 'varchar', nullable: false, comment: '订单状态' },
            { name: 'total_amount', type: 'decimal', nullable: false, comment: '订单总金额' },
            { name: 'shipping_address', type: 'varchar', nullable: false, comment: '收货地址' },
            { name: 'payment_method', type: 'varchar', nullable: false, comment: '支付方式' },
            { name: 'created_at', type: 'timestamp', nullable: false, comment: '创建时间' },
            { name: 'updated_at', type: 'timestamp', nullable: false, comment: '更新时间' }
        ]
    },
    {
        name: 'order_item',
        comment: '订单项表',
        columns: [
            { name: 'id', type: 'int', nullable: false, isPrimary: true, comment: '订单项ID' },
            { name: 'order_id', type: 'int', nullable: false, comment: '订单ID' },
            { name: 'product_id', type: 'int', nullable: false, comment: '产品ID' },
            { name: 'quantity', type: 'int', nullable: false, comment: '数量' },
            { name: 'price', type: 'decimal', nullable: false, comment: '价格' },
            { name: 'created_at', type: 'timestamp', nullable: false, comment: '创建时间' }
        ]
    },
    {
        name: 'category',
        comment: '分类表',
        columns: [
            { name: 'id', type: 'int', nullable: false, isPrimary: true, comment: '分类ID' },
            { name: 'name', type: 'varchar', nullable: false, comment: '分类名称' },
            { name: 'parent_id', type: 'int', nullable: true, comment: '父分类ID' },
            { name: 'created_at', type: 'timestamp', nullable: false, comment: '创建时间' },
            { name: 'updated_at', type: 'timestamp', nullable: false, comment: '更新时间' }
        ]
    }
];

/**
 * 生成表的Markdown文档
 */
function generateTableDoc(table) {
    const docPath = path.join(OUTPUT_DIR, `${table.name}.md`);

    let content = `# ${table.name} 表\n\n`;
    content += `**描述**: ${table.comment}\n\n`;
    content += `## 表结构\n\n`;
    content += `| 字段名 | 类型 | 可空 | 主键 | 描述 |\n`;
    content += `| ------ | ---- | ---- | ---- | ---- |\n`;

    table.columns.forEach(column => {
        content += `| ${column.name} | ${column.type} | ${column.nullable ? '是' : '否'} | ${column.isPrimary ? '是' : '否'} | ${column.comment} |\n`;
    });

    content += `\n## API示例\n\n`;
    content += `### 查询${table.name}表数据\n\n`;
    content += "```javascript\n";
    content += `// 查询${table.name}表数据\n`;
    content += `const response = await fetch('/api/${table.name}/list', {\n`;
    content += `  method: 'GET',\n`;
    content += `  headers: {\n`;
    content += `    'Content-Type': 'application/json',\n`;
    content += `    'Authorization': 'Bearer ${token}'\n`;
    content += `  }\n`;
    content += `});\n\n`;
    content += `const data = await response.json();\n`;
    content += `console.log(data);\n`;
    content += "```\n";

    fs.writeFileSync(docPath, content);
    console.log(`生成表文档: ${docPath}`);
}

/**
 * 生成表的TypeScript类型定义
 */
function generateTableType(table) {
    const typePath = path.join(TYPES_DIR, `${table.name}.ts`);

    let content = `/**\n * ${table.comment} 类型定义\n */\n\n`;
    content += `export interface ${capitalizeFirstLetter(table.name)} {\n`;

    table.columns.forEach(column => {
        const tsType = mapSqlTypeToTs(column.type);
        content += `  /**\n   * ${column.comment}\n   */\n`;
        content += `  ${column.name}${column.nullable ? '?' : ''}: ${tsType};\n\n`;
    });

    content += `}\n`;

    fs.writeFileSync(typePath, content);
    console.log(`生成类型定义: ${typePath}`);
}

/**
 * 生成表的原始数据文件
 */
function generateRawData(table) {
    const tableDir = path.join(RAW_DATA_DIR, table.name);
    if (!fs.existsSync(tableDir)) {
        fs.mkdirSync(tableDir, { recursive: true });
    }

    // 生成列数据
    const columnsPath = path.join(tableDir, 'columns.json');
    const columnsData = table.columns.map(column => ({
        columnName: column.name,
        dataType: column.type,
        isNullable: column.nullable ? 'YES' : 'NO',
        columnDefault: null,
        isPrimaryKey: column.isPrimary ? 'YES' : 'NO',
        columnComment: column.comment
    }));

    fs.writeFileSync(columnsPath, JSON.stringify({
        tableName: table.name,
        columns: columnsData,
        tableComment: table.comment,
        createdAt: new Date().toISOString()
    }, null, 2));

    // 生成索引数据
    const indexesPath = path.join(tableDir, 'indexes.json');
    const indexData = table.columns
        .filter(column => column.isPrimary)
        .map(column => ({
            indexName: 'PRIMARY',
            columnName: column.name,
            isUnique: 'YES',
            indexType: 'BTREE'
        }));

    fs.writeFileSync(indexesPath, JSON.stringify({
        tableName: table.name,
        indexes: indexData,
        createdAt: new Date().toISOString()
    }, null, 2));

    // 生成外键数据
    const foreignKeysPath = path.join(tableDir, 'foreignKeys.json');
    fs.writeFileSync(foreignKeysPath, JSON.stringify({
        tableName: table.name,
        foreignKeys: [],
        createdAt: new Date().toISOString()
    }, null, 2));

    console.log(`生成表原始数据: ${tableDir}`);
}

/**
 * 生成表概述
 */
function generateTablesSummary() {
    const summaryPath = path.join(RAW_DATA_DIR, 'metadata', 'tables_summary.json');
    if (!fs.existsSync(path.dirname(summaryPath))) {
        fs.mkdirSync(path.dirname(summaryPath), { recursive: true });
    }

    const summary = MOCK_TABLES.map(table => ({
        tableName: table.name,
        tableComment: table.comment,
        columnsCount: table.columns.length,
        createdAt: new Date().toISOString()
    }));

    fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2));
    console.log(`生成表概述: ${summaryPath}`);
}

/**
 * 生成类型索引文件
 */
function generateTypeIndex() {
    const indexPath = path.join(TYPES_DIR, 'index.ts');

    let content = `/**\n * 类型定义索引文件\n */\n\n`;

    MOCK_TABLES.forEach(table => {
        const typeName = capitalizeFirstLetter(table.name);
        content += `import { ${typeName} } from './${table.name}';\n`;
    });

    content += '\nexport {\n';
    MOCK_TABLES.forEach(table => {
        content += `  ${capitalizeFirstLetter(table.name)},\n`;
    });
    content += '};\n';

    fs.writeFileSync(indexPath, content);
    console.log(`生成类型索引: ${indexPath}`);
}

/**
 * 辅助函数：首字母大写
 */
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

/**
 * 辅助函数：SQL类型映射到TypeScript类型
 */
function mapSqlTypeToTs(sqlType) {
    const typeMap = {
        'int': 'number',
        'decimal': 'number',
        'float': 'number',
        'double': 'number',
        'varchar': 'string',
        'char': 'string',
        'text': 'string',
        'timestamp': 'Date',
        'date': 'Date',
        'datetime': 'Date',
        'boolean': 'boolean'
    };

    return typeMap[sqlType.toLowerCase()] || 'any';
}

/**
 * 主函数
 */
function main() {
    console.log('开始生成模拟表数据...');

    // 从token文件中获取token供API示例使用
    let token = '模拟令牌';
    try {
        const tokenPath = path.join(__dirname, 'token.json');
        if (fs.existsSync(tokenPath)) {
            const tokenData = JSON.parse(fs.readFileSync(tokenPath, 'utf8'));
            token = tokenData.token;
        }
    } catch (error) {
        console.warn('未能读取令牌文件，使用默认令牌');
    }

    // 生成每个表的数据
    MOCK_TABLES.forEach(table => {
        console.log(`\n处理表: ${table.name}`);
        generateTableDoc(table);
        generateTableType(table);
        generateRawData(table);
    });

    // 生成汇总数据
    generateTablesSummary();
    generateTypeIndex();

    console.log('\n模拟数据生成完成!');
}

// 执行主函数
main(); 